﻿using AutoMapper;
using Decoration.Api.Comm;
using Decoration.Comm;
using Decoration.IService;
using Decoration.Models;
using Decoration.Models.Dto;
using Decoration.Models.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace Decoration.Api.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    [MyAuthorize]
    public class OrderInfoController : ControllerBase
    {
        private readonly IOrderInfoService svc;
        private readonly IUserInfoService userSvc;
        private readonly ICustomerInfoService customerSvc;
        private readonly IWF_NodeService nodeSvc;
        private readonly IWF_InstanceService instanceSvc;
        private readonly IWF_RecordService recordSvc;
        private readonly IMapper mapper;

        public OrderInfoController(IOrderInfoService svc,IUserInfoService userSvc,ICustomerInfoService customerSvc,IWF_NodeService nodeSvc,IWF_InstanceService instanceSvc,IWF_RecordService recordSvc,IMapper mapper)
        {
            this.svc = svc;
            this.userSvc = userSvc;
            this.customerSvc = customerSvc;
            this.nodeSvc = nodeSvc;
            this.instanceSvc = instanceSvc;
            this.recordSvc = recordSvc;
            this.mapper = mapper;
        }

        /// <summary>
        /// 获取全部
        /// </summary>
        /// <returns></returns>
        [HttpGet("getAll")]
        public Result Get()
        {
            var data = svc.Query(o => o.Status == 1);

            return new Result() { code = 1, msg = "成功", data = data };
        }

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="id">订单编号</param>
        /// <param name="pageSize"></param>
        /// <param name="pageIndex"></param>
        /// <returns></returns>
        [HttpGet]
        public PagedResult<OrderDto> Get(int? id = null, int pageSize = 10, int pageIndex = 1)
        {
            string sql = @" select o.*
		                    ,oT.DictName as 'OrderTypeName'
							,approval.DictName as 'ApprovalStatusText'
		                    ,business.BusinessName
							,u.UserName as 'CreaterName'
		                    from OrderInfos o
		                    inner join vw_dict oT on o.OrderType = oT.DictValue and oT.DictTypeName = '订单类型'
							inner join vw_dict approval on o.ApprovalStatus = approval.DictValue and approval.DictTypeName = '审批状态'
		                    inner join BusinessInfos business on o.BusinessId = business.Id
							inner join Base_UserInfos u on u.Id = o.Creater
		                    where 1=1";

            if (id != null) sql += " and o.Id = @id";

            string countSql = $"select count(*) from ({sql})";

            int total = svc.ExecuteScalar<int>(sql, new { id });

            sql += " order by createTime desc";
            sql += " offset @pageSize*(@pageIndex-1) rows fetch next @pageSize rows only";

            var data = svc.Query<OrderDto>(sql, new { id , pageSize, pageIndex });

            return new PagedResult<OrderDto>() { code = 1, msg = "成功", total = total, data = data };
        }

        /// <summary>
        /// 查询我的
        /// </summary>
        /// <param name="id">订单编号</param>
        /// <param name="pageSize"></param>
        /// <param name="pageIndex"></param>
        /// <returns></returns>
        [HttpGet("getMy")]
        public PagedResult<OrderDto> GetMy(int? id = null, int pageSize = 10, int pageIndex = 1)
        {
            var auth = RouteData.Values["auth"] as AuthInfo;

            string sql = @" select o.*
		                    ,oT.DictName as 'OrderTypeName'
							,approval.DictName as 'ApprovalStatusText'
		                    ,business.BusinessName
		                    from OrderInfos o
		                    inner join vw_dict oT on o.OrderType = oT.DictValue and oT.DictTypeName = '订单类型'
							inner join vw_dict approval on o.ApprovalStatus = approval.DictValue and approval.DictTypeName = '审批状态'
		                    inner join BusinessInfos business on o.BusinessId = business.Id
		                    where Creater=@UserId";

            if (id != null) sql += " and o.Id = @id";

            string countSql = $"select count(*) from ({sql})";

            int total = svc.ExecuteScalar<int>(sql, new { id,auth.UserId });

            sql += " order by createTime desc";
            sql += " offset @pageSize*(@pageIndex-1) rows fetch next @pageSize rows only";

            var data = svc.Query<OrderDto>(sql, new { id, auth.UserId, pageSize, pageIndex });

            return new PagedResult<OrderDto>() { code = 1, msg = "成功", total = total, data = data };
        }

        /// <summary>
        /// 获取我的审批
        /// </summary>
        /// <param name="id"></param>
        /// <param name="pageSize"></param>
        /// <param name="pageIndex"></param>
        /// <returns></returns>
        [HttpGet("getApproval")]
        public PagedResult<OrderDto> GetApproval(int? id = null, int pageSize = 10, int pageIndex = 1)
        {
            var auth = RouteData.Values["auth"] as AuthInfo;

            string sql = @" select o.*
	                    ,oT.DictName as 'OrderTypeName'
	                    ,business.BusinessName
                        ,u.UserName as 'CreaterName'
	                    from OrderInfos o
	                    inner join WF_Instances i on o.Id = i.ApplicationId and i.ApplicationTypeId = 1 and i.FlowStatus = 1
	                    inner join vw_dict oT on o.OrderType = oT.DictValue and oT.DictTypeName = '订单类型'
	                    inner join BusinessInfos business on o.BusinessId = business.Id
                        inner join Base_UserInfos u on u.Id = o.Creater
                        where o.Creater = @UserId";

            if (id != null) sql += " and o.Id = @id";

            string countSql = $"select count(*) from ({sql})";

            int total = svc.ExecuteScalar<int>(sql, new { id, auth.UserId });

            sql += " order by createTime desc";
            sql += " offset @pageSize*(@pageIndex-1) rows fetch next @pageSize rows only";

            var data = svc.Query<OrderDto>(sql, new { id, auth.UserId, pageSize, pageIndex });

            return new PagedResult<OrderDto>() { code = 1, msg = "成功", total = total, data = data };
        }

        /// <summary>
        /// 获取单个
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public Result Get(int id)
        {
            var data = svc.Get(o => o.Id == id);

            if (data == null) return new Result() { code = -1, msg = "数据不存在" };

            return new Result() { code = 1, msg = "成功", data = data };
        }

        /// <summary>
        /// 新增订单
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        public Result Post(OrderProjectPostDto dto)
        {
            var auth = RouteData.Values["auth"] as AuthInfo;

            var entity = mapper.Map<OrderInfo>(dto);

            entity.Creater = auth.UserId;

            var customer = customerSvc.Get(o => o.Id == dto.Customer);

            if (customer == null) return new Result() { code = -1, msg = "客户不存在" };
            entity.CustomerName = customer.CustomerName;

            if (svc.Add(entity))
                return new Result() { code = 1, msg = "成功" };
            else
                return new Result() { code = 1, msg = "失败" };
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="id"></param>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPut]
        public Result Put(long id, OrderPutOrder dto)
        {
            var data = svc.Get(o => o.Id == id);

            if (data == null) return new Result() { code = -1, msg = "数据不存在" };

            var entity = mapper.Map(dto, data);

            if (svc.Update(entity))
                return new Result() { code = 1, msg = "成功" };
            else
                return new Result() { code = -1, msg = "失败" };
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete]
        public Result Delete(int id)
        {
            var data = svc.Get(o => o.Id == id);

            if (data == null) return new Result() { code = -1, msg = "数据不存在" };

            data.Status = 0;

            if (svc.Update(data))
                return new Result() { code = 1, msg = "成功" };
            else
                return new Result() { code = -1, msg = "失败" };
        }

        /// <summary>
        /// 提审
        /// </summary>
        /// <returns></returns>
        [HttpPost("send")]
        public Result Send(int typeCode,int orderId)
        {
            var auth = RouteData.Values["auth"] as AuthInfo;

            // 获取订单
            var order = svc.Get(o=>o.Id == orderId);
            if (order == null) return new Result() { code = -1, msg = "订单不存在" };

            // 获取提审用户
            var user = userSvc.Get(u=>u.Id == auth.UserId);
            if (user == null) return new Result() { code = -1, msg = "用户不存在" };

            // 获取流程类型的初始节点
            var startNode = nodeSvc.Get(n=>n.TypeCode == typeCode&&n.PrevNodeCode==0);
            if (startNode == null) return new Result() { code = -1, msg = "节点不存在" };

            // 获取下一节点
            var nextNode = nodeSvc.Get(n=>n.NodeCode == startNode.NextNodeCode);

            // 获取下一节点审批人
            string sql = @"select u.*
	                    from Base_UserInfos u
	                    inner join Base_UserRoles ur on u.Id = ur.UserId and ur.RoleId = @RoleId
	                    where 1=1";

            // 判断节点是否关联部门
            if (startNode.IsUseDept == 1)
                sql += " and deptId = @deptId";

            var approver = DapperHelper.QueryFirstOrDefault<Base_UserInfo>(sql,new { nextNode.RoleId,user.DeptId});
            if (approver == null) return new Result() { code = -1, msg = "不存在符合的审批人" };

            // 创建流程
            var instances = new WF_Instance()
            {
                ApplicationId = orderId,
                ApplicationTypeId = 1,
                NodeCode = startNode.NodeCode,
                NodeName = startNode.NodeName,
                FlowStatus = 1,
                StarterId = user.Id,
                Starter = user.UserName,
                OperatorId = user.Id,
                Operator = user.UserName,
                ToDoerId = approver.Id,
                ToDoer = approver.UserName,
                Status = 1,
                CreateTime = DateTime.Now,
                UpdateTime = DateTime.Now,
            };

            instanceSvc.Add(instances);

            // 添加审批记录
            var record = new WF_Record()
            {
                WFId = instances.Id,
                ApplicationId = orderId,
                ApplicationTypeId = 1,
                NodeCode = startNode.NodeCode,
                NodeName = startNode.NodeName,
                OperatorId = user.Id,
                Operator = user.UserName,
                ApprovalOpinions = "提审成功",
                ApprovalStatus = 3,
                Status = 1,
                CreateTime = DateTime.Now,
            };

            recordSvc.Add(record);

            // 修改订单审批状态
            order.ApprovalStatus = 2;

            if (svc.Update(order))
                return new Result() { code = 1, msg = "提审成功" };
            else
                return new Result() { code = -1, msg = "提审失败" };
        }

        /// <summary>
        /// 审批
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("approval")]
        public Result Approval(OrderApprovalDto dto)
        {
            var auth = RouteData.Values["auth"] as AuthInfo;

            // 获取当前操作人
            var currentUser = userSvc.Get(u => u.Id == auth.UserId);

            // 获取审批订单
            var order = svc.Get(o => o.Id == dto.OrderId);

            // 获取审批实例
            var instance = instanceSvc.Get(i => i.ApplicationId == dto.OrderId && i.ApplicationTypeId == 1 && i.FlowStatus == 1);

            // 获取当前审批节点
            var currentNode = nodeSvc.Get(n => n.PrevNodeCode == instance.NodeCode);
            instance.NodeCode = currentNode.NodeCode;
            instance.NodeName = currentNode.NodeName;

            // 修改操作人
            instance.Operator = currentUser.UserName;
            instance.OperatorId = currentUser.Id;

            // 添加审批记录
            var record = new WF_Record()
            {
                WFId = instance.Id,
                ApplicationId = (int)instance.ApplicationId,
                ApplicationTypeId = instance.ApplicationTypeId,
                NodeCode = currentNode.NodeCode,
                NodeName = currentNode.NodeName,
                OperatorId = currentUser.Id,
                Operator = currentUser.UserName,
                ApprovalOpinions = dto.ApprovalOpinions,
                ApprovalStatus = dto.ApprovalStatus,
                Status = 1,
                CreateTime = DateTime.Now,
            };

            // 获取下一节点
            var nextNode = nodeSvc.Get(n=>n.PrevNodeCode == currentNode.NodeCode);

            if(nextNode == null)
            {
                // 不存在下一节点
                instance.FlowStatus = 2;

                order.ApprovalStatus = record.ApprovalStatus;
            }
            else
            {
                // 存在
                // 获取下一节点审批人
                string sql = @"select u.*
	                    from Base_UserInfos u
	                    inner join Base_UserRoles ur on u.Id = ur.UserId and ur.RoleId = @RoleId
	                    where 1=1";

                // 判断节点是否关联部门
                if (nextNode.IsUseDept == 1)
                    sql += " and deptId = @deptId";

                var approver = DapperHelper.QueryFirstOrDefault<Base_UserInfo>(sql, new { nextNode.RoleId, currentUser.DeptId });
                if (approver == null) return new Result() { code = -1, msg = "不存在符合的审批人" };

                instance.ToDoerId = approver.Id;
                instance.ToDoer = approver.UserName;
            }

            instance.UpdateTime = DateTime.Now;

            // 更新订单
            svc.Update(order);
            instanceSvc.Update(instance);
            if (recordSvc.Add(record))
                return new Result() { code = 1, msg = "审批成功" };
            else
                return new Result() { code = -1, msg = "审批失败" };
        }
    }
}
